/**
 * @file mysql_manager.h
 * @brief 数据库管理器
 * @details 管理Mysql数据库连接和文件元数据操作
 */

#pragma once

#include <mysql/mysql.h>
#include "connpool.h"
#include <string>
#include <memory>
#include <mutex>

/**
 * @struct FileInfo
 * @brief 文件信息结构体
 */
struct FileInfo 
{
    std::string id;           ///< 6位文件ID
    std::string hash;         ///< 文件SHA-256哈希值
    std::string filename;     ///< 原始文件名
    uint64_t filesize;        ///< 文件大小
    std::string mime_type;    ///< MIME类型
    std::string upload_time;  ///< 上传时间
    int download_count;       ///< 下载次数
};

/**
 * @class MysqlManager
 * @brief 数据库管理器类
 * @details 单例模式的Mysql数据库管理器，提供文件元数据的CRUD操作
 */
class MysqlManager 
{
public:
    /**
     * @brief 获取单例实例
     * @return DatabaseManager& 数据库管理器实例
     */
    static MysqlManager& getInstance();
    
    /**
     * @brief 初始化数据库
     * @return bool 初始化是否成功
     */
    bool init();
    
    /**
     * @brief 插入文件信息
     * @param file_info 文件信息
     * @return bool 插入是否成功
     */
    bool insertFile(const FileInfo& file_info);
    
    /**
     * @brief 根据ID查询文件信息
     * @param id 文件ID
     * @param file_info 输出文件信息
     * @return bool 查询是否成功
     */
    bool getFileById(const std::string& id, FileInfo& file_info);
    
    /**
     * @brief 根据哈希值查询文件信息
     * @param hash 文件哈希值
     * @param file_info 输出文件信息
     * @return bool 查询是否成功
     */
    bool getFileByHash(const std::string& hash, FileInfo& file_info);
    
    /**
     * @brief 更新下载次数
     * @param id 文件ID
     * @return bool 更新是否成功
     */
    bool updateDownloadCount(const std::string& id);
    
    /**
     * @brief 检查ID是否存在
     * @param id 文件ID
     * @return bool ID是否存在
     */
    bool isIdExists(const std::string& id);
    
    /**
     * @brief 检查哈希值是否存在
     * @param hash 文件哈希值
     * @return bool 哈希值是否存在
     */
    bool isHashExists(const std::string& hash);

private:
    MysqlManager();
    ~MysqlManager() = default;
    
    // 禁用拷贝构造和赋值操作
    MysqlManager(const MysqlManager&) = delete;
    MysqlManager& operator=(const MysqlManager&) = delete;
    
    /**
     * @brief 创建数据表
     * @return bool 创建是否成功
     */
    bool createTables();
    

private:
    ConnectionPool* pool_ = nullptr;
    std::mutex mutex_;                         ///< 线程安全锁
}; 